Dynomotion

Group: DynoMotion Message: 6487 From: himykabibble Date: 1/15/2013
Subject: Threads And Locks And Invokes
Tom/Brad,

I think I've finally got a fair handle on threading issues, and how/when to use Invoke. I've been able to get my app *mostly* working again, but I'm still having a few problems related to threading and/or locks. I'm not at all clear on when/how to use locks. I see this construct used in the example code:

if (KMController.WaitToken(100) == KMOTION_TOKEN.KMOTION_LOCKED)
{
try {
Do something here....
KMController.RelaseLock();
} catch {DMException e1) {
KMController.RelaseLock();
....
} catch ....
}

WHEN should this be used? On ALL accesses? I'm not currently doing this anywhere...

Regards,
Ray L.
Group: DynoMotion Message: 6489 From: Tom Kerekes Date: 1/15/2013
Subject: Re: Threads And Locks And Invokes
Hi Ray,

The idea of Locking (WaitToken) is to avoid having multiple Threads or Application Processes getting the KFLOP Command/Responses mixed up.

There are other built in mechanisms that avoid Threading problems for you so you can essentially consider sending strings and receiving strings as atomic operations. 

So for simple things like sending "SetBit46" to KFLOP you don't need to do anything other than call WriteLine(); 

For a command with a single line of response such as "ReadBit46", WriteLineReadLine() can be used which has a built in WaitToken/Release Token so again nothing extra is required.

Only commands that require multiple contiguous commands ie writing a large amount of data, or reading a large amount of data (more than one line) require WaitToken and ReleaseToken.  GetStatus is such a case (and probably the only one you will need to worry about).  KFLOP returns the status as multiple lines of Hexidecimal data and we must assure that all the ReadLines are performed by the Thread that requested the status.

HTH
Regards
TK


Group: DynoMotion Message: 6490 From: himykabibble Date: 1/16/2013
Subject: Re: Threads And Locks And Invokes
Tom,

OK, that makes sense. I'm doing everything through dotNet, so I shouldn't even have to worry about GetStatus, right? Just today I started having a new problem where I do a single-word read from Persist using WriteLineReadLine, but somehow I'm ending up sometimes with huge string of values coming back, like I'd requested a read of a large block of values. I haven't gotten to the bottom of that one yet, but I must still be having some kind of threading issue that hosing things. I'll have to go through it all with a fine tooth comb again. I've found quite a few things that needed cleaning up.

Regards,
Ray L.

--- In DynoMotion@yahoogroups.com, Tom Kerekes wrote:
>
> Hi Ray,
>
> The idea of Locking (WaitToken) is to avoid having multiple Threads or Application Processes getting the KFLOP Command/Responses mixed up.
>
> There are other built in mechanisms that avoid Threading problems for you so you can essentially consider sending strings and receiving strings as atomic operations. 
>
> So for simple things like sending "SetBit46" to KFLOP you don't need to do anything other than call WriteLine(); 
>
> For a command with a single line of response such as "ReadBit46", WriteLineReadLine() can be used which has a built in WaitToken/Release Token so again nothing extra is required.
>
> Only commands that require multiple contiguous commands ie writing a large amount of data, or reading a large amount of data (more than one line) require WaitToken and ReleaseToken.  GetStatus is such a case (and probably the only one you will need to worry about).  KFLOP returns the status as multiple lines of Hexidecimal data and we must assure that all the ReadLines are performed by the Thread that requested the status.
>
> HTH
> Regards
> TK
>
>
>
>
> ________________________________
> From: himykabibble
> To: DynoMotion@yahoogroups.com
> Sent: Tuesday, January 15, 2013 2:29 PM
> Subject: [DynoMotion] Threads And Locks And Invokes
>
>
>  
> Tom/Brad,
>
> I think I've finally got a fair handle on threading issues, and how/when to use Invoke. I've been able to get my app *mostly* working again, but I'm still having a few problems related to threading and/or locks. I'm not at all clear on when/how to use locks. I see this construct used in the example code:
>
> if (KMController.WaitToken(100) == KMOTION_TOKEN.KMOTION_LOCKED)
> {
> try {
> Do something here....
> KMController.RelaseLock();
> } catch {DMException e1) {
> KMController.RelaseLock();
> ....
> } catch ....
> }
>
> WHEN should this be used? On ALL accesses? I'm not currently doing this anywhere...
>
> Regards,
> Ray L.
>
Group: DynoMotion Message: 6496 From: himykabibble Date: 1/16/2013
Subject: Re: Threads And Locks And Invokes
Hmmmm..... This doesn't make a lot of sense to me. I have been using GetStatus to get a local copy of MainStatus, then using that for my GUI updates. I was running into what looked like comms problems - getting bad data back from WriteLineReadLine when I'd do Persist reads. e.g. - I would request a single word, and get back a looooong string of a dozen or more words. I changed to using the dotNet automatic MainStatus updates with an interval of 100mSec, and the problem is now gone, and all seems to be working properly. This is, IIRC, similar to the problem I had a year ago with MainStatus.

KM_Controller.GetUserData - this reads Persist? I'm currently doing it using WriteLineReadLine.

Regards,
Ray L.

--- In DynoMotion@yahoogroups.com, "himykabibble" wrote:
>
> Tom,
>
> OK, that makes sense. I'm doing everything through dotNet, so I shouldn't even have to worry about GetStatus, right? Just today I started having a new problem where I do a single-word read from Persist using WriteLineReadLine, but somehow I'm ending up sometimes with huge string of values coming back, like I'd requested a read of a large block of values. I haven't gotten to the bottom of that one yet, but I must still be having some kind of threading issue that hosing things. I'll have to go through it all with a fine tooth comb again. I've found quite a few things that needed cleaning up.
>
> Regards,
> Ray L.
>
> --- In DynoMotion@yahoogroups.com, Tom Kerekes wrote:
> >
> > Hi Ray,
> >
> > The idea of Locking (WaitToken) is to avoid having multiple Threads or Application Processes getting the KFLOP Command/Responses mixed up.
> >
> > There are other built in mechanisms that avoid Threading problems for you so you can essentially consider sending strings and receiving strings as atomic operations. 
> >
> > So for simple things like sending "SetBit46" to KFLOP you don't need to do anything other than call WriteLine(); 
> >
> > For a command with a single line of response such as "ReadBit46", WriteLineReadLine() can be used which has a built in WaitToken/Release Token so again nothing extra is required.
> >
> > Only commands that require multiple contiguous commands ie writing a large amount of data, or reading a large amount of data (more than one line) require WaitToken and ReleaseToken.  GetStatus is such a case (and probably the only one you will need to worry about).  KFLOP returns the status as multiple lines of Hexidecimal data and we must assure that all the ReadLines are performed by the Thread that requested the status.
> >
> > HTH
> > Regards
> > TK
> >
> >
> >
> >
> > ________________________________
> > From: himykabibble
> > To: DynoMotion@yahoogroups.com
> > Sent: Tuesday, January 15, 2013 2:29 PM
> > Subject: [DynoMotion] Threads And Locks And Invokes
> >
> >
> >  
> > Tom/Brad,
> >
> > I think I've finally got a fair handle on threading issues, and how/when to use Invoke. I've been able to get my app *mostly* working again, but I'm still having a few problems related to threading and/or locks. I'm not at all clear on when/how to use locks. I see this construct used in the example code:
> >
> > if (KMController.WaitToken(100) == KMOTION_TOKEN.KMOTION_LOCKED)
> > {
> > try {
> > Do something here....
> > KMController.RelaseLock();
> > } catch {DMException e1) {
> > KMController.RelaseLock();
> > ....
> > } catch ....
> > }
> >
> > WHEN should this be used? On ALL accesses? I'm not currently doing this anywhere...
> >
> > Regards,
> > Ray L.
> >
>
Group: DynoMotion Message: 6502 From: Tom Kerekes Date: 1/16/2013
Subject: Re: Threads And Locks And Invokes
 
Hi Ray,
 
The long list of Hex values that you sometimes get is probably GetStatus data where a mixup occurred.
 
The idea with the Locked parameter to GetStatus is to let GetStatus know whether you are handling the Token or whether you want it to be handled automatically internally.
 
The method in the examples and in the method I tested and recommended was handling the Token externally.  This has the benefit of you knowing what happened.  Either the status was updated or not, whether there was an error, or whether something else was using the board for a long time and we decided to not wait (unlike most other commands, status might be considered on a "best effort" basis).  Try Getting/Releasing the Tokes as shown in the examples and see if that solves the problem.
 
It looks to me like there is a bug in the internal lock mechanism of GetStatus.   It attempts to get the token properly, but regardless if successful or not it goes ahead and issues and reads all the Status lines.
 
See below.
 
Regards
TK 
 
 
 
 
 
int
CKMotionDLL::GetStatus(MAIN_STATUS& status, bool lock)
{
int i,result,n,token;
CString s;
int *p=(int *)&status;
if(lock)
{
token = WaitToken( false, 100);
}
// KMotion is available read the status
s.Format(
"GetStatus");
if (WriteLine(s)) return 1;
n=
sizeof(status)/sizeof(int);
s.Empty();
for (i=0; i<n; i++)
{
if (s.IsEmpty())
{
if (ReadLineTimeOut(s.GetBuffer(257),5000))
{
return 1;
}
s.ReleaseBuffer();
// change the CRLF at the to a space
s.Delete(s.GetLength()-2,2);
s +=
' ';
}
// get a hex 32 bit int which may really be anything
result = sscanf(s.GetBuffer(0),
"%8X",p++);
if (result!=1)
{
return 1;
}
if (s.GetLength() >=9)
{
s.Delete(0,9);
}
else
{
return 1;
}
// check if first word contains version
if (i==0)
{
if ((p[-1]>>16)==306) // check for previous version
{
}
if ((p[-1]>>16)==0)
{
// probably old version of DSP Code
// set version to something
status.VersionAndSize=0;
status.ThreadActive=0;
p[0] = p[-1];
p++;
n=n-2;
}
}
}
if(lock)
{
if(token == KMOTION_LOCKED)
{
ReleaseToken();
return 0;
}
else
{
return 1;
}
}
return 0;
}
 

Group: DynoMotion Message: 6503 From: himykabibble Date: 1/16/2013
Subject: Re: Threads And Locks And Invokes
Tom,

That is what I suspected, and is consistent with the symptoms I was seeing - most of the time it worked, but when I generated more "traffic" on the interface by executing more commands (kicking off a G-code run), then I'd start seeing this error. My app appears to be working perfectly now letting dotNet do the MainStatus updates. At this point, I'm not sure I really need to know if GetStatus fails, because I'm doing enough other accesses, if the board goes out to lunch, I'll know about it due to those other accesses failing, and I now handle failures fairly gracefully. Is there a reasonable scenario where the MainStatus updates could fail, but everything else keeps working properly? Seems to me it will mostly either work correctly, or not at all, due to the board disconnecting. If an occasional status update fails, it won't cause me any problem, as long as I get a correct one reasonably soon.

Do you see the same lock bug in the "internal" MainStatus update code as well, or just in GetStatus?

If you get the GetStatus bug fixed, I can easily switch my app back to test it.

Regards,
Ray L.

--- In DynoMotion@yahoogroups.com, Tom Kerekes wrote:
>
>  
> Hi Ray,
>  
> The long list of Hex values that you sometimes get is probably GetStatus data where a mixup occurred.
>  
> The idea with the Locked parameter to GetStatus is to let GetStatus know whether you are handling the Token or whether you want it to be handled automatically internally.
>  
> The method in the examples and in the method I tested and recommended was handling the Token externally.  This has the benefit of you knowing what happened.  Either the status was updated or not, whether there was an error, or whether something else was using the board for a long time and we decided to not wait (unlike most other commands, status might be considered on a "best effort" basis).  Try Getting/Releasing the Tokes as shown in the examples and see if that solves the problem.
>  
> It looks to me like there is a bug in the internal lock mechanism of GetStatus.   It attempts to get the token properly, but regardless if successful or not it goes ahead and issues and reads all the Status lines.
>  
> See below.
>  
> Regards
> TK 
>  
>  
>  
>  
>  int
> {
> CString s;
> {
> token = WaitToken(
> }CKMotionDLL::GetStatus(MAIN_STATUS& status, boollock)inti,result,n,token;int*p=(int*)&status;if(lock)false, 100);// KMotion is available read the statuss.Format(
> n=
> s.Empty();
> {
> {
> {
> }
> s.ReleaseBuffer();"GetStatus"); if(WriteLine(s)) return1;sizeof(status)/sizeof(int);for(i=0; i
s +=
> }' ';// get a hex 32 bit int which may really be anythingresult = sscanf(s.GetBuffer(0),
> {
> }
> {
> s.Delete(0,9);
> }"%8X",p++);if(result!=1)return1;if(s.GetLength() >=9)else{
> }return1;// check if first word contains version{if(i==0)if((p[-1]>>16)==306) // check for previous version{
> }
> {if((p[-1]>>16)==0)// probably old version of DSP Code// set version to somethingstatus.VersionAndSize=0;
> status.ThreadActive=0;
> p[0] = p[-1];
> p++;
> n=n-2;
> }
> }
> }
> {
> {
> ReleaseToken();
> }if(lock)if(token == KMOTION_LOCKED)return0;else{
> }
> }
> }return1;return0;
>  
>
>
> ________________________________
> From: himykabibble
> To: DynoMotion@yahoogroups.com
> Sent: Wednesday, January 16, 2013 9:25 AM
> Subject: [DynoMotion] Re: Threads And Locks And Invokes
>
>  
> Hmmmm..... This doesn't make a lot of sense to me. I have been using GetStatus to get a local copy of MainStatus, then using that for my GUI updates. I was running into what looked like comms problems - getting bad data back from WriteLineReadLine when I'd do Persist reads. e.g. - I would request a single word, and get back a looooong string of a dozen or more words. I changed to using the dotNet automatic MainStatus updates with an interval of 100mSec, and the problem is now gone, and all seems to be working properly. This is, IIRC, similar to the problem I had a year ago with MainStatus.
>
> KM_Controller.GetUserData - this reads Persist? I'm currently doing it using WriteLineReadLine.
>
> Regards,
> Ray L.
>
> --- In mailto:DynoMotion%40yahoogroups.com, "himykabibble" wrote:
> >
> > Tom,
> >
> > OK, that makes sense. I'm doing everything through dotNet, so I shouldn't even have to worry about GetStatus, right? Just today I started having a new problem where I do a single-word read from Persist using WriteLineReadLine, but somehow I'm ending up sometimes with huge string of values coming back, like I'd requested a read of a large block of values. I haven't gotten to the bottom of that one yet, but I must still be having some kind of threading issue that hosing things. I'll have to go through it all with a fine tooth comb again. I've found quite a few things that needed cleaning up.
> >
> > Regards,
> > Ray L.
> >
> > --- In mailto:DynoMotion%40yahoogroups.com, Tom Kerekes wrote:
> > >
> > > Hi Ray,
> > >
> > > The idea of Locking (WaitToken) is to avoid having multiple Threads or Application Processes getting the KFLOP Command/Responses mixed up.
> > >
> > > There are other built in mechanisms that avoid Threading problems for you so you can essentially consider sending strings and receiving strings as atomic operations. 
> > >
> > > So for simple things like sending "SetBit46" to KFLOP you don't need to do anything other than call WriteLine(); 
> > >
> > > For a command with a single line of response such as "ReadBit46", WriteLineReadLine() can be used which has a built in WaitToken/Release Token so again nothing extra is required.
> > >
> > > Only commands that require multiple contiguous commands ie writing a large amount of data, or reading a large amount of data (more than one line) require WaitToken and ReleaseToken.  GetStatus is such a case (and probably the only one you will need to worry about).  KFLOP returns the status as multiple lines of Hexidecimal data and we must assure that all the ReadLines are performed by the Thread that requested the status.
> > >
> > > HTH
> > > Regards
> > > TK
> > >
> > >
> > >
> > >
> > > ________________________________
> > > From: himykabibble
> > > To: mailto:DynoMotion%40yahoogroups.com
> > > Sent: Tuesday, January 15, 2013 2:29 PM
> > > Subject: [DynoMotion] Threads And Locks And Invokes
> > >
> > >
> > >  
> > > Tom/Brad,
> > >
> > > I think I've finally got a fair handle on threading issues, and how/when to use Invoke. I've been able to get my app *mostly* working again, but I'm still having a few problems related to threading and/or locks. I'm not at all clear on when/how to use locks. I see this construct used in the example code:
> > >
> > > if (KMController.WaitToken(100) == KMOTION_TOKEN.KMOTION_LOCKED)
> > > {
> > > try {
> > > Do something here....
> > > KMController.RelaseLock();
> > > } catch {DMException e1) {
> > > KMController.RelaseLock();
> > > ....
> > > } catch ....
> > > }
> > >
> > > WHEN should this be used? On ALL accesses? I'm not currently doing this anywhere...
> > >
> > > Regards,
> > > Ray L.
> > >
> >
>
Group: DynoMotion Message: 6504 From: himykabibble Date: 1/16/2013
Subject: Re: Threads And Locks And Invokes
Tom,

I've got it working now with both methods. I was using GetStatus(false). Oops! Sorry for the wild goose chase. Sounds like you did find a dotNet bug, though, which is good!

All these changes have been a lot of work, but I feel like I've got a much more robust, maintainable app now.

Regards,
Ray L.

--- In DynoMotion@yahoogroups.com, "himykabibble" wrote:
>
> Tom,
>
> That is what I suspected, and is consistent with the symptoms I was seeing - most of the time it worked, but when I generated more "traffic" on the interface by executing more commands (kicking off a G-code run), then I'd start seeing this error. My app appears to be working perfectly now letting dotNet do the MainStatus updates. At this point, I'm not sure I really need to know if GetStatus fails, because I'm doing enough other accesses, if the board goes out to lunch, I'll know about it due to those other accesses failing, and I now handle failures fairly gracefully. Is there a reasonable scenario where the MainStatus updates could fail, but everything else keeps working properly? Seems to me it will mostly either work correctly, or not at all, due to the board disconnecting. If an occasional status update fails, it won't cause me any problem, as long as I get a correct one reasonably soon.
>
> Do you see the same lock bug in the "internal" MainStatus update code as well, or just in GetStatus?
>
> If you get the GetStatus bug fixed, I can easily switch my app back to test it.
>
> Regards,
> Ray L.
>
> --- In DynoMotion@yahoogroups.com, Tom Kerekes wrote:
> >
> >  
> > Hi Ray,
> >  
> > The long list of Hex values that you sometimes get is probably GetStatus data where a mixup occurred.
> >  
> > The idea with the Locked parameter to GetStatus is to let GetStatus know whether you are handling the Token or whether you want it to be handled automatically internally.
> >  
> > The method in the examples and in the method I tested and recommended was handling the Token externally.  This has the benefit of you knowing what happened.  Either the status was updated or not, whether there was an error, or whether something else was using the board for a long time and we decided to not wait (unlike most other commands, status might be considered on a "best effort" basis).  Try Getting/Releasing the Tokes as shown in the examples and see if that solves the problem.
> >  
> > It looks to me like there is a bug in the internal lock mechanism of GetStatus.   It attempts to get the token properly, but regardless if successful or not it goes ahead and issues and reads all the Status lines.
> >  
> > See below.
> >  
> > Regards
> > TK 
> >  
> >  
> >  
> >  
> >  int
> > {
> > CString s;
> > {
> > token = WaitToken(
> > }CKMotionDLL::GetStatus(MAIN_STATUS& status, boollock)inti,result,n,token;int*p=(int*)&status;if(lock)false, 100);// KMotion is available read the statuss.Format(
> > n=
> > s.Empty();
> > {
> > {
> > {
> > }
> > s.ReleaseBuffer();"GetStatus"); if(WriteLine(s)) return1;sizeof(status)/sizeof(int);for(i=0; i
> s +=
> > }' ';// get a hex 32 bit int which may really be anythingresult = sscanf(s.GetBuffer(0),
> > {
> > }
> > {
> > s.Delete(0,9);
> > }"%8X",p++);if(result!=1)return1;if(s.GetLength() >=9)else{
> > }return1;// check if first word contains version{if(i==0)if((p[-1]>>16)==306) // check for previous version{
> > }
> > {if((p[-1]>>16)==0)// probably old version of DSP Code// set version to somethingstatus.VersionAndSize=0;
> > status.ThreadActive=0;
> > p[0] = p[-1];
> > p++;
> > n=n-2;
> > }
> > }
> > }
> > {
> > {
> > ReleaseToken();
> > }if(lock)if(token == KMOTION_LOCKED)return0;else{
> > }
> > }
> > }return1;return0;
> >  
> >
> >
> > ________________________________
> > From: himykabibble
> > To: DynoMotion@yahoogroups.com
> > Sent: Wednesday, January 16, 2013 9:25 AM
> > Subject: [DynoMotion] Re: Threads And Locks And Invokes
> >
> >  
> > Hmmmm..... This doesn't make a lot of sense to me. I have been using GetStatus to get a local copy of MainStatus, then using that for my GUI updates. I was running into what looked like comms problems - getting bad data back from WriteLineReadLine when I'd do Persist reads. e.g. - I would request a single word, and get back a looooong string of a dozen or more words. I changed to using the dotNet automatic MainStatus updates with an interval of 100mSec, and the problem is now gone, and all seems to be working properly. This is, IIRC, similar to the problem I had a year ago with MainStatus.
> >
> > KM_Controller.GetUserData - this reads Persist? I'm currently doing it using WriteLineReadLine.
> >
> > Regards,
> > Ray L.
> >
> > --- In mailto:DynoMotion%40yahoogroups.com, "himykabibble" wrote:
> > >
> > > Tom,
> > >
> > > OK, that makes sense. I'm doing everything through dotNet, so I shouldn't even have to worry about GetStatus, right? Just today I started having a new problem where I do a single-word read from Persist using WriteLineReadLine, but somehow I'm ending up sometimes with huge string of values coming back, like I'd requested a read of a large block of values. I haven't gotten to the bottom of that one yet, but I must still be having some kind of threading issue that hosing things. I'll have to go through it all with a fine tooth comb again. I've found quite a few things that needed cleaning up.
> > >
> > > Regards,
> > > Ray L.
> > >
> > > --- In mailto:DynoMotion%40yahoogroups.com, Tom Kerekes wrote:
> > > >
> > > > Hi Ray,
> > > >
> > > > The idea of Locking (WaitToken) is to avoid having multiple Threads or Application Processes getting the KFLOP Command/Responses mixed up.
> > > >
> > > > There are other built in mechanisms that avoid Threading problems for you so you can essentially consider sending strings and receiving strings as atomic operations. 
> > > >
> > > > So for simple things like sending "SetBit46" to KFLOP you don't need to do anything other than call WriteLine(); 
> > > >
> > > > For a command with a single line of response such as "ReadBit46", WriteLineReadLine() can be used which has a built in WaitToken/Release Token so again nothing extra is required.
> > > >
> > > > Only commands that require multiple contiguous commands ie writing a large amount of data, or reading a large amount of data (more than one line) require WaitToken and ReleaseToken.  GetStatus is such a case (and probably the only one you will need to worry about).  KFLOP returns the status as multiple lines of Hexidecimal data and we must assure that all the ReadLines are performed by the Thread that requested the status.
> > > >
> > > > HTH
> > > > Regards
> > > > TK
> > > >
> > > >
> > > >
> > > >
> > > > ________________________________
> > > > From: himykabibble
> > > > To: mailto:DynoMotion%40yahoogroups.com
> > > > Sent: Tuesday, January 15, 2013 2:29 PM
> > > > Subject: [DynoMotion] Threads And Locks And Invokes
> > > >
> > > >
> > > >  
> > > > Tom/Brad,
> > > >
> > > > I think I've finally got a fair handle on threading issues, and how/when to use Invoke. I've been able to get my app *mostly* working again, but I'm still having a few problems related to threading and/or locks. I'm not at all clear on when/how to use locks. I see this construct used in the example code:
> > > >
> > > > if (KMController.WaitToken(100) == KMOTION_TOKEN.KMOTION_LOCKED)
> > > > {
> > > > try {
> > > > Do something here....
> > > > KMController.RelaseLock();
> > > > } catch {DMException e1) {
> > > > KMController.RelaseLock();
> > > > ....
> > > > } catch ....
> > > > }
> > > >
> > > > WHEN should this be used? On ALL accesses? I'm not currently doing this anywhere...
> > > >
> > > > Regards,
> > > > Ray L.
> > > >
> > >
> >
>